树莓派 4 开发箱

您所在的位置:网站首页 docker 代替 树莓派 4 开发箱

树莓派 4 开发箱

#树莓派 4 开发箱| 来源: 网络整理| 查看: 265

玩弄 Docker 容器,我想设置一个 Raspberry Pi 4 作为各种项目的终极主机。在这篇文章中,我将尝试解释我是如何将 Raspberry Pi 完全变成终极主机的。

第一个问题是我希望在它们各自的标准端口上公开多个服务,但是如果我以通常的方式分配端口,例如 -p 12345:12345,我只能在该端口上公开一个服务。这还不够好。

多个静态IP

我的 Pi 设置为始终从 dhcp 接收 192.168.1.40,我知道从 41 到 49 没有任何内容,因此我可以使用该设置。为了分配它们,我创建了/etc/dhcpcd.exit-hook具有以下内容

# just eth0 interface [ "${interface}" = "eth0" ] || exit 0 # after dhcp address is assigned [ "${reason}" = BOUND ] || exit 0 # only if there are no secondary addresses assigned ! ip addr show | grep -q 'secondary eth0:' || exit 0 ip addr add 192.168.1.41/24 dev eth0 label eth0:1 ip addr add 192.168.1.42/24 dev eth0 label eth0:2 ip addr add 192.168.1.43/24 dev eth0 label eth0:3 ip addr add 192.168.1.44/24 dev eth0 label eth0:4 ip addr add 192.168.1.45/24 dev eth0 label eth0:5 ip addr add 192.168.1.45/24 dev eth0 label eth0:5 ip addr add 192.168.1.46/24 dev eth0 label eth0:6 ip addr add 192.168.1.47/24 dev eth0 label eth0:7 ip addr add 192.168.1.48/24 dev eth0 label eth0:8 ip addr add 192.168.1.49/24 dev eth0 label eth0:9

好的,所以在 Pi 通过 DHCP 获得 IP 地址后,它会为自己分配额外的 9 个 IP 地址。现在我有 10 个不同的地址可供使用。

比如我可以在192.168.1.41上运行一个数据库

docker run -d --name postgres12 \ --restart unless-stopped \ -v /srv/postgres12/data:/var/lib/postgresql/data \ --env-file /srv/postgres12/vars.env \ --network skynet \ -p 192.168.1.41:5432:5432 \ postgres:12-alpine

另一个在 192.168.1.46

docker run -d --name postgres11 \ --restart unless-stopped \ -v /srv/postgres11/data:/var/lib/postgresql/data \ --env-file /srv/postgres11/vars.env \ --network groundnet \ -p 192.168.1.46:5432:5432 \ postgres:11-alpine

并且它们都暴露在我的本地网络上以便于管理(使用 pgAdmin 或其他东西)。这个例子展示了两个不同的 pgsql 版本,11 和 12,但它可以是一个用于数据库的 IP,另一个用于 Web 服务器。

Web 服务器

现在,谈论我可以轻松运行的 Web 服务器

docker run -d --name mycoolserver \ --restart unless-stopped \ -v /srv/mycoolserver/server:/opt/mycoolserver \ -v /srv/mycoolserver/data:/var/opt/mycoolserver \ -w="/opt/mycoolserver" \ --network skynet -p 192.168.1.42:80:80 mcr.microsoft.com/dotnet/core/aspnet dotnet MyCoolServer.dll

现在我也暴露了 aspnet 核心站点。鉴于这是默认的 webapi 项目,如果我在浏览器中打开http://192.168.1.42/weatherforecast,我应该会得到一些随机的预测数据。

或者只是为了让它更简单,使用 PHP 开发服务器

只需创建 file/srv/phptest/index.php

并运行它

docker run -d --name phptest \ -v /srv/phptest:/srv/www \ --network skynet \ php:alpine php -S 0.0.0.0:80 -t /srv/www

这个没有暴露在主机上,所以是时候以某种方式使其可用了。

反向代理 - Traefik

使用 Traefik 作为反向代理,所有这些内部服务都可以通过一个 IP 地址公开。

Traefik 使用 docker api 提供了出色的发现,但由于这只是各种项目的设置,我更喜欢手动设置所有内容。配置文件traefik.toml仅定义侦听目录中文件更改的文件提供程序。这使我可以在该目录中放置其他配置文件或更改某些内容,Traefik 几乎会立即刷新配置。

[entryPoints] [entryPoints.web] address = ":80" [entryPoints.websecure] address = ":443" [providers] [providers.file] directory = "/etc/traefik/conf" watch = true [api] insecure = true [log] level = "DEBUG" [accessLog]

用 docker 启动它

docker run -d --name traefik \ --restart unless-stopped \ -v /srv/traefik/traefik.toml:/etc/traefik/traefik.toml \ -v /srv/traefik/conf:/etc/traefik/conf \ --network skynet \ -p 192.168.1.43:8080:8080 \ -p 192.168.1.43:443:443 \ -p 192.168.1.43:80:80 \ traefik

有了 Traefik,我想使用域名而不是 IP 地址来访问它。为此,我可以写一条线

192.168.1.43 devbox

进入主机文件(Windows 上的 c:\Windows\System32\drivers\etc\hosts 或 Linux 上的 /etc /hosts),但由于我的路由器正在运行 dnsmasq,所以我将

address=/devbox/192.168.1.43

进入 dnsmasq 自定义配置。这也适用于子域,而不是每个域必须独立设置的主机文件。

现在我可以使用https://devbox:8080访问 Traefik 的仪表板。太好了,继续。

动态配置需要定义路由器、入口点、服务等,但最棒的是它还支持模板。有了模板,我可以复制文件并更改两个变量,名称和域。

{{ $name := ""}} {{ $domain := "" }} [http.routers] [http.routers.{{$name}}-http] entryPoints = ["web"] rule = "Host(\"{{$name}}.{{$domain}}\")" middlewares = ["https-only"] service = "{{$name}}" [http.routers.{{$name}}-https] entryPoints = ["websecure"] rule = "Host(\"{{$name}}.{{$domain}}\")" service = "{{$name}}" [http.routers.{{$name}}-https.tls] [[http.services.{{$name}}.loadBalancer.servers]] url = "http://{{$name}}/"

使用这个模板我可以创建 phptest.toml。请注意,仅 https 中间件已被删除以允许标准 http 连接。后面会解释 Https。

{{ $name := "phptest"}} {{ $domain := "devbox" }} [http.routers] [http.routers.{{$name}}-http] entryPoints = ["web"] rule = "Host(\"{{$name}}.{{$domain}}\")" service = "{{$name}}" [http.routers.{{$name}}-https] entryPoints = ["websecure"] rule = "Host(\"{{$name}}.{{$domain}}\")" service = "{{$name}}" [http.routers.{{$name}}-https.tls] [[http.services.{{$name}}.loadBalancer.servers]] url = "http://{{$name}}/"

正确的。因此,这会创建两个路由器,一个用于 http,一个用于 https,设置适当的入口点并在负载均衡器后面创建一个服务,即使对于一台服务器,该服务也必须存在于 Traefik 中。 Traefik 将模板理解为:

[http.routers] [http.routers.phptest-http] entryPoints = ["web"] rule = "Host(\"phptest.devbox\")" service = "phptest" [http.routers.phptest-https] entryPoints = ["websecure"] rule = "Host(\"phptest.devbox\")" service = "phptest" [http.routers.phptest-https.tls] [[http.services.phptest.loadBalancer.servers]] url = "http://phptest/"

为服务和子域使用相同的名称使事情变得容易。但如果需要,它也可以轻松更改。

尝试在浏览器中访问http://phptest.devbox会显示标准的 PHP 信息页面。

HTTPS

从 http 的角度来看一切都很好,但现在一切都是 https。并且尝试访问https://phptest.devbox会使浏览器尖叫“不安全”。第一个想法是安装 Teaefik 的默认证书,或者甚至创建您自己的证书(自签名、本地 ca、...)。但这样做的问题是,如果你想通过手机测试一个网站,它会再次尖叫无效证书,并且在手机和其他设备上安装额外的证书只是痛苦的。

替代方法是使用通常受信任的 Let's Encrypt 证书。但是要使用 Let's Encrypt,我们需要一个有效的域。是时候放弃 devbox 域并购买常规 tld。有大量 gTLD 可供选择,并且考虑到这将主要在内部使用,建议选择短而便宜的。

一旦购买了域名(我们称之为devbox.tld而不是标准的example.com),根据域名注册商,Traefik 可以自行获取证书。但同样,这是一个开发/测试多个项目的游乐场,所以让另一个服务来处理证书是有意义的,以防某些服务不通过 Traefik。

Acme.sh

Acme.sh 是一个纯 Unix shell 脚本,它实现了 ACME 客户端协议来获取 Let's Encrypt 证书。https://github.com/Neilpang/acme.sh

docker hub 上没有用于 Raspberry Pi 的 docker 容器,但可以从源代码轻松构建。在空文件夹中运行:

git clone https://github.com/Neilpang/acme.sh.git . docker build -t neilpang/acme.sh:arm32v7 .

之后在 docker 容器中启动它

docker run -itd --name acme.sh \ --restart unless-stopped \ -v "/srv/certs":/acme.sh \ neilpang/acme.sh:arm32v7 daemon

为主域和该域的通配符请求证书。这将涵盖devbox.tld、phptest.devbox.tld、mycoolserver.devbox.tld等。拥有一个通配符证书非常干净。

docker exec acme.sh --issue --dns -d 'devbox.tld' -d '*.devbox.tld' 放在一起

现在获得了证书,是时候把所有东西放在一起了。

在所有 docker run 命令中,我安装了本地文件夹,而不是让 docker 创建卷。这是因为我更喜欢在玩耍时轻松访问所有配置、数据等。这可能不是应该投入生产的东西,但是对于开发和测试各种场景,它很容易管理。证书在 /srv/certs 目录,traefik 在 /srv/traefik,mycoolserver 在 /srv/mycoolserver 等等。

流量

回到 Traefik。由于原始 docker run 命令行不包含证书文件夹,因此可以停止、删除并再次运行容器,将证书挂载为

docker run -d --name traefik \ --restart unless-stopped \ -v /srv/traefik/traefik.toml:/etc/traefik/traefik.toml \ -v /srv/traefik/conf:/etc/traefik/conf \ -v /srv/certs:/etc/traefik/ssl \ --network skynet \ -p 192.168.1.43:8080:8080 \ -p 192.168.1.43:443:443 \ -p 192.168.1.43:80:80 \ traefik

在配置目录中,创建新的 default_ssl.toml 以加载证书并将 http 设置为 https 重定向中间件。

[http.middlewares] [http.middlewares.https-only.redirectScheme] scheme = "https" [[tls.certificates]] certFile = "/etc/traefik/ssl/devbox.tld/fullchain.cer" keyFile = "/etc/traefik/ssl/devbox.tld/devbox.tld.key"

最后是 phptest.toml,现在有了正确的 TLD 和活动的中间件。

{{ $name := "phptest"}} {{ $domain := "devbox.tld" }} [http.routers] [http.routers.{{$name}}-http] entryPoints = ["web"] rule = "Host(\"{{$name}}.{{$domain}}\")" middlewares = ["https-only"] service = "{{$name}}" [http.routers.{{$name}}-https] entryPoints = ["websecure"] rule = "Host(\"{{$name}}.{{$domain}}\")" service = "{{$name}}" [http.routers.{{$name}}-https.tls] [[http.services.{{$name}}.loadBalancer.servers]] url = "http://{{$name}}/" 路由器

在路由器上,在 dnsmasq 配置下添加

address=/devbox.tld/192.168.1.43

(或在主机中添加)

192.168.1.43 devbox.tld 192.168.1.43 phptest.devbox.tld

就是这样。打开http://devbox.tld:8080显示 Traefik 的仪表板,http://phptest.devbox.tld重定向到https://phptest.devbox.tld并显示 PHP 信息页面。一切都在手机上运行,没有警告或错误。

最后的想法

这背后的想法是建立一个游乐场,用于在简单廉价的环境中开发和测试各种场景、Web 应用程序、服务等。

代替 Raspberry Pi,它可以在 Hyper-V linux 机器上运行。连接到外部虚拟交换机的 Hyper-V 客户机上的最小 debian 安装 + docker 应该可以解决问题。

而不是仅在内部使用域,而是为购买的域设置动态 dns + cname 以及将路由器上的 443 端口转发到 traefik 将允许外部访问以测试 webhook 或类似内容。

每个容器都是自己启动的,而不是使用 docker compose,因为我可以轻松地停止一个容器,而其他容器不受影响。我可以将 Traefik 与 Nginx 或 Acme.sh 与 Certbot 或其他东西交换。通过挂载卷,数据可以在 Pi 上持久保存并轻松访问(如果挂载在 Pi 上,甚至可以在 NAS 上)。

网络也是根据需要定义的,所以几个容器可以在一个网络上,几个在另一个网络上,等等。

并且在 docker 主机上设置多个静态 IP 地址可以让它成为一个非常小的包中的“整个公司网络”。

无论如何,我希望你觉得这个想法很有趣。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3